#include "ul_mod_define.h"
#include <algorithm>
#include "ul_atomic.h"
#include "ul_log_adapter.h"

LinuxNetworkUtility::UlModInfo LinuxNetworkUtility::UL_MOD_SET[G_MAX_MOD_NUM]; 

LinuxNetworkUtility::UlModSet::UlModSet()
{
  init_ul_mod_set();
  mod_num_ = std::min<int32_t>(UlModIds::UL_MOD_END, G_MAX_MOD_NUM);
  memset(mod_memory_usage_,0x00,sizeof(mod_memory_usage_));
}

int32_t LinuxNetworkUtility::UlModSet::get_mod_id(const char * mod_name)const
{
  int32_t result = 0;
  if (NULL == mod_name)
  {
    result = 0;
  }
  for (int32_t mod_idx = 0; 
      mod_idx < mod_num_ && 0 == result && NULL != mod_name; 
      mod_idx ++)
  {
    if (strcmp(UL_MOD_SET[mod_idx].mod_name_, mod_name) == 0)
    {
      result = mod_idx;
      break;
    }
  }
  return result;
}

const char * LinuxNetworkUtility::UlModSet::get_mod_name(const int32_t mod_id) const
{
  const char *result = NULL;
  if (mod_id < 0 || mod_id >= mod_num_)
  {
    result = UL_MOD_SET[0].mod_name_;
  }
  else
  {
    result = UL_MOD_SET[mod_id].mod_name_;
  }
  return result;
}

int32_t LinuxNetworkUtility::UlModSet::get_max_mod_num()const
{
  return mod_num_;
}

void LinuxNetworkUtility::UlModSet::malloc(const int64_t size, const int32_t mod_id)
{
  int32_t real_mod_id = 0;
  if(mod_id >= mod_num_ || mod_id < 0)
  {
    real_mod_id = 0;
  }
  else
  {
    real_mod_id = mod_id;
  }
  atomic_add((uint64_t*)(mod_memory_usage_ + real_mod_id), (const uint64_t)size);
}

void LinuxNetworkUtility::UlModSet::free(const int64_t size, const int32_t mod_id)
{
  int32_t real_mod_id = 0;
  if(mod_id >= mod_num_ || mod_id < 0)
  {
    real_mod_id = 0;
  }
  else
  {
    real_mod_id = mod_id;
  }
  atomic_add((uint64_t*)(mod_memory_usage_ + real_mod_id), (const uint64_t)(size*-1));
}


void LinuxNetworkUtility::UlModSet::print_mod_memory_usage()
{
  for(int32_t mod_idx = 0; mod_idx < mod_num_; mod_idx++)
  {
    UL_LOG_MONITOR("module memory usage [mod_name:%s,usage:%lld]",UL_MOD_SET[mod_idx].mod_name_, mod_memory_usage_[mod_idx]);
  }
}
